﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using ETModel;

namespace ETHotfix {
    /// <summary>
    /// 在Gate服务器管理GateLoginKey的组件
    /// </summary>
    public class GateLoginKeyComponent : Component {
        private readonly Dictionary<string, string> AccountGateLoginKeys = new Dictionary<string, string>();
        private readonly Dictionary<string, CancellationTokenSource> AccountGateLoginKeysRemoveTask = new Dictionary<string, CancellationTokenSource>();

        /// <summary>
        /// 根据帐号生成会话标识
        /// </summary>
        /// <param name="userAccount"></param>
        /// <returns></returns>
        public string BuildGateLoginKey(string userAccount) {

            //先根据用户帐号查找是否之前有生成但未使用的
            CancellationTokenSource removeCancel;
            if (AccountGateLoginKeysRemoveTask.TryGetValue(userAccount, out removeCancel)) {
                removeCancel.Cancel();
            }

            //重新生成一个
            removeCancel = new CancellationTokenSource();
            string GateLoginKey = Guid.NewGuid().ToString("N");

            this.AccountGateLoginKeys[userAccount] = GateLoginKey;
            this.AccountGateLoginKeysRemoveTask[userAccount] = removeCancel;

            //异步等待一定时间要删除
            this.TimeoutRemoveKey(userAccount, removeCancel.Token).Coroutine();

            return GateLoginKey;
        }

        /// <summary>
        /// 验证账户和会话标识,成功会清理会话标识
        /// </summary>
        /// <param name="userAccount"></param>
        /// <param name="GateLoginKey"></param>
        /// <returns></returns>
        public bool CheckGateLoginKey(string userAccount, string GateLoginKey) {
            if (string.IsNullOrEmpty(GateLoginKey)) {
                return false;
            }
            if (AccountGateLoginKeys.GetValueOrDefault(userAccount) != GateLoginKey) {
                return false;
            }

            AccountGateLoginKeys.Remove(userAccount);
            AccountGateLoginKeysRemoveTask.Remove(userAccount);
            return true;
        }

        private async ETVoid TimeoutRemoveKey(string key, CancellationToken cancellationToken) {
            await Game.Scene.GetComponent<TimerComponent>().WaitAsync(20000, cancellationToken);
            if (!cancellationToken.IsCancellationRequested) {
                AccountGateLoginKeys.Remove(key);
                AccountGateLoginKeysRemoveTask.Remove(key);
            }
        }
    }
}
